import {request} from './request';
import {Method} from 'axios';
import {LoginUser, User} from '@/model/UserClass';
import {Ref} from 'vue';
import {ApiAuthUser, ApiCode, ApiResponse} from '@/model/ApiClass';
import {ElMessage} from 'element-plus';
import ccRouter from '@/router';
import {RouteNameEnum} from '@/model/RouterClass';
import store from '@/store/index';
import {Loading} from '@/model/LoadingClass';
import {loadingUtil} from '@/util/LoadingUtil';

export const enum RequestUrlEnum {
  userLogin = '/user/login',
  userInfoByToken = '/user/getUserByToken',
  userLogout = '/user/logout',
  testList = 'test/testList',
}

const methodList: { methodGet: Method, methodPost: Method } = {
  methodGet: 'get',
  methodPost: 'post',
};

/**
 * 请求的统一处理方法
 * @param urlName 请求地址
 * @param config 配置参数
 * @param loadingEnv loading状态，在接口返回error的时候终止loading
 */
// tslint:disable-next-line:max-line-length
function api<T>(urlName: RequestUrlEnum, config: { data?: any, params?: any, method: Method }, loadingEnv?: Ref<boolean> | Loading | undefined): Promise<ApiResponse<any>> {
  return new Promise((resolve, reject) => {
    const req = request({
      method: config.method,
      url: urlName.toString(),
      data: config.data,
      params: config.params,
    });
    req.then((value) => {
      if ((value.headers['content-type']).includes('application/json')) {
        const data = value.data as ApiResponse<T>;
        if (data.code === ApiCode.Success) {
          resolve(data);
        } else if (data.code === ApiCode.Fail) {
          ElMessage({duration: 1000, type: 'error', message: data.msg as string});
          throw new Error(data.msg as string);
        } else if (data.code === ApiCode.TokenExpired || data.code === ApiCode.NotLogin) {
          const message: string = data.code === ApiCode.TokenExpired ? 'token已过期，请重新登录' : '您还未登录系统';
          ElMessage({duration: 1000, type: 'error', message});
          ccRouter.replace({routeName: RouteNameEnum.login}).then((r) => {
            store.commit('user/setToken', null);
          });
        }
      }
      resolve(value.data);
    }).catch((reason) => {
      loadingUtil.endLoading(loadingEnv);
      reject(reason);
    });
  });
}

/**
 * 用户登录接口
 * @param data 请求参数
 * @param loadingEnv?? loading的状态对象
 * @return
 */
// tslint:disable-next-line:max-line-length
function apiUserLogin(data: LoginUser, loadingEnv?: Ref<boolean> | Loading | undefined): Promise<ApiResponse<ApiAuthUser>> {
  return api(RequestUrlEnum.userLogin, {data, method: methodList.methodPost}, loadingEnv);
}

/**
 * 根据token从缓存中获取到用户的个人信息
 * @param loadingEnv loading的状态对象
 */
function apiGetUserInfoByToken(loadingEnv?: Ref<boolean>): Promise<ApiResponse<User>> {
  return api(RequestUrlEnum.userInfoByToken, { method: methodList.methodGet });
}

/**
 * 退出登录
 * @param loadingEnv
 */
function apiUserLogout(loadingEnv?: Ref<boolean>): Promise<ApiResponse<User>> {
  return api(RequestUrlEnum.userLogout, { method: methodList.methodPost });
}

function apiTestList(loadingEnv?: Ref<boolean>): Promise<ApiResponse<any>> {
  return api(RequestUrlEnum.testList, {method: methodList.methodPost, data: {userName: '12'}});
}



export const apiMethod = {
  apiUserLogin,
  apiGetUserInfoByToken,
  apiUserLogout,
  apiTestList,
};
